package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.annotation.PromiseStyleMinVersion
import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.Value2Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.Promise

////////////////////
// Omnibox
////////////////////
/**
 * The omnibox API allows you to register a keyword with Google Chrome's address bar, which is also known as the omnibox.
 *
 * Manifest: "omnibox"
 */
interface Omnibox {
    // Sets the description and styling for the default suggestion.
    // The default suggestion is the text that is displayed in the first suggestion row underneath the URL bar.
    @PromiseStyleMinVersion(100)
     fun setDefaultSuggestion(
        // A partial SuggestResult object, without the 'content' parameter.
        suggestResult: DefaultSuggestResult,
        callback: VoidFunction? = null
    ): Promise<Void>

    // User has deleted a suggested result.
    // @callback {callback.text}
    @PromiseStyleMinVersion(63)
     val onDeleteSuggestion: Events.Event<Value1Function<String>>

    // User has ended the keyword input session without accepting the input.
     val onInputCancelled: Events.Event<VoidFunction>

    // User has changed what is typed into the omnibox.
    // @callback {text, suggest: (suggestResults: Array<SuggestResult>) => void}
     val onInputChanged: Events.Event<Value2Function<String, Value1Function<List<SuggestResult>>>>

    // User has accepted what is typed into the omnibox.
     val onInputEntered: Events.Event<Value2Function<String, OnInputEnteredDisposition>>

    // User has started a keyword input session by typing the extension's keyword.
    // This is guaranteed to be sent exactly once per input session, and before any onInputChanged events.
     val onInputStarted: Events.Event<VoidFunction>

    data class DefaultSuggestResult(
        // The text that is displayed in the URL dropdown.
        // Can contain XML-style markup for styling.
        // The supported tags are 'url' (for a literal URL), 'match' (for highlighting text that matched what the user's query),
        // and 'dim' (for dim helper text).
        // The styles can be nested, eg. dimmed match.
        var description: String,
    )

    // The style type.
    @ChromeMinVersion(44)
    enum class DescriptionStyleType {
        url,
        match,
        dim
    }

    // The window disposition for the omnibox query.
    // This is the recommended context to display results.
    // For example, if the omnibox command is to navigate to a certain URL,
    // a disposition of 'newForegroundTab' means the navigation should take place in a new selected tab.
    @ChromeMinVersion(44)
    enum class OnInputEnteredDisposition {
        currentTab,
        newForegroundTab,
        newBackgroundTab
    }

    // A suggest result.
    data class SuggestResult(
        // The text that is put into the URL bar, and that is sent to the extension when the user chooses this entry.
        var content: String,
        // Whether the suggest result can be deleted by the user.
        @ChromeMinVersion(63)
        var deletable: Boolean?,
        // The text that is displayed in the URL dropdown.
        // Can contain XML-style markup for styling.
        // The supported tags are 'url' (for a literal URL),
        // 'match' (for highlighting text that matched what the user's query),
        // and 'dim' (for dim helper text).
        // The styles can be nested, eg. dimmed match.
        // You must escape the five predefined entities to display them as text: stackoverflow.com/a/1091953/89484
        var description: String,
    )
}